﻿using UnityEngine;
using UnityEngine.Events;

namespace EntityKit.Runtime
{
    /// <summary>
    /// 可拖动对象
    /// </summary>
    [DisallowMultipleComponent]
    public sealed class GameObjectDrag : MonoBehaviour
    {
        /// <summary>
        /// 是否启用全局拖拽
        /// </summary>
        public static bool IsAllowDragEnvironment = true;

        /// <summary>
        /// 是否启用拖拽
        /// </summary>
        public bool IsAllowDrag = true;

        /// <summary>
        /// 开始拖拽事件
        /// </summary>
        public UnityEvent BeginDragEvent;

        /// <summary>
        /// 拖拽中事件
        /// </summary>
        public UnityEvent DragingEvent;

        /// <summary>
        /// 结束拖拽事件
        /// </summary>
        public UnityEvent EndDragEvent;

        private Vector3 _offset;
        private bool _isDraging = false;

        /// <summary>
        /// 是否可以拖拽
        /// </summary>
        public bool IsCanDrag
        {
            get { return IsAllowDragEnvironment && IsAllowDrag; }
        }

        private void OnMouseDown()
        {
            if (IsCanDrag)
            {
                Vector3 mousePoint = Input.mousePosition;
                if (Camera.main == null) return;
                Vector3 screenPoint = Camera.main.WorldToScreenPoint(transform.position);
                mousePoint.z = screenPoint.z = 0;
                _offset = screenPoint - mousePoint;
            }
        }

        private void OnMouseDrag()
        {
            if (IsCanDrag)
            {
                Vector3 mousePoint = Input.mousePosition;
                if (Camera.main == null) return;
                Vector3 screenPoint = Camera.main.WorldToScreenPoint(transform.position);
                mousePoint.z = screenPoint.z;
                transform.position = Camera.main.ScreenToWorldPoint(mousePoint + _offset);

                if (!_isDraging)
                {
                    _isDraging = true;
                    BeginDragEvent.Invoke();
                }
                else
                {
                    DragingEvent.Invoke();
                }
            }
        }

        private void OnMouseUp()
        {
            if (IsCanDrag)
            {
                _offset = Vector3.zero;

                if (_isDraging)
                {
                    _isDraging = false;
                    EndDragEvent.Invoke();
                }
            }
        }
    }
}